home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / admin / dig-2.0 / dig-2 / dig.2.0 / res_debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-04  |  13.9 KB  |  705 lines

  1.  
  2. /*
  3.  * Copyright (c) 1985 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted
  7.  * provided that this notice is preserved and that due credit is given
  8.  * to the University of California at Berkeley. The name of the University
  9.  * may not be used to endorse or promote products derived from this
  10.  * software without specific prior written permission. This software
  11.  * is provided ``as is'' without express or implied warranty.
  12.  */
  13.  
  14. /*
  15. ** Modified for and distributed with 'dig' version 2.0 from 
  16. ** University of Southern California Information Sciences Institute
  17. ** (USC-ISI). 9/1/90
  18. */
  19.  
  20.  
  21. #if defined(LIBC_SCCS) && !defined(lint)
  22. static char sccsid[] = "@(#)res_debug.c    5.22 (Berkeley) 3/7/88";
  23. #endif /* LIBC_SCCS and not lint */
  24.  
  25. #if defined(lint) && !defined(DEBUG)
  26. #define DEBUG
  27. #endif
  28.  
  29. #ifndef RES_DEBUG
  30. #define RES_DEBUG2      0x80000000
  31. #endif
  32.  
  33. #include "hfiles.h"
  34.  
  35. #include <sys/types.h>
  36. #include <netinet/in.h>
  37. #include <stdio.h>
  38. #include NAMESERH
  39. #ifndef T_TXT
  40. #define T_TXT 16
  41. #endif T_TXT
  42. #include RESOLVH
  43. #include "pflag.h"
  44. #include NETDBH
  45.  
  46.  
  47. extern char *p_cdname(), *p_rr(), *p_type(), *p_class();
  48. extern char *inet_ntoa();
  49.  
  50. char *_res_opcodes[] = {
  51.     "QUERY",
  52.     "IQUERY",
  53.     "CQUERYM",
  54.     "CQUERYU",
  55.     "4",
  56.     "5",
  57.     "6",
  58.     "7",
  59.     "8",
  60.     "UPDATEA",
  61.     "UPDATED",
  62.  
  63.     "UPDATEDA",
  64.     "UPDATEM",
  65.     "UPDATEMA",
  66.     "ZONEINIT",
  67.     "ZONEREF",
  68. };
  69.  
  70. char *_res_resultcodes[] = {
  71.     "NOERROR",
  72.     "FORMERR",
  73.     "SERVFAIL",
  74.     "NXDOMAIN",
  75.     "NOTIMP",
  76.     "REFUSED",
  77.     "6",
  78.     "7",
  79.     "8",
  80.     "9",
  81.     "10",
  82.     "11",
  83.     "12",
  84.     "13",
  85.     "14",
  86.     "NOCHANGE",
  87. };
  88.  
  89.  
  90. static char wksbuf[16];
  91.  
  92. char * dewks(wks)
  93.    int wks;
  94. {
  95.     switch (wks) {
  96.     case 5: return("rje");
  97.     case 7: return("echo");
  98.     case 9: return("discard");
  99.     case 11: return("systat");
  100.     case 13: return("daytime");
  101.     case 15: return("netstat");
  102.     case 17: return("qotd");
  103.     case 19: return("chargen");
  104.     case 20: return("ftp-data");
  105.     case 21: return("ftp");
  106.     case 23: return("telnet");
  107.     case 25: return("smtp");
  108.     case 37: return("time");
  109.     case 39: return("rlp");
  110.     case 42: return("name");
  111.     case 43: return("whois");
  112.     case 53: return("domain");
  113.     case 57: return("apts");
  114.     case 59: return("apfs");
  115.     case 67: return("bootps");
  116.     case 68: return("bootpc");
  117.     case 69: return("tftp");
  118.     case 77: return("rje");
  119.     case 79: return("finger");
  120.     case 87: return("link");
  121.     case 95: return("supdup");
  122.     case 100: return("newacct");
  123.     case 101: return("hostnames");
  124.     case 102: return("iso-tsap");
  125.     case 103: return("x400");
  126.     case 104: return("x400-snd");
  127.     case 105: return("csnet-ns");
  128.     case 109: return("pop-2");
  129.     case 111: return("sunrpc");
  130.     case 113: return("auth");
  131.     case 115: return("sftp");
  132.     case 117: return("uucp-path");
  133.     case 119: return("nntp");
  134.     case 121: return("erpc");
  135.     case 123: return("ntp");
  136.     case 133: return("statsrv");
  137.     case 136: return("profile");
  138.     case 144: return("NeWS");
  139.     case 161: return("snmp");
  140.     case 162: return("snmp-trap");
  141.     case 170: return("print-srv");
  142.     default: (void) sprintf(wksbuf, "%d", wks);
  143.              return(wksbuf);
  144.     }
  145.   }
  146.  
  147. char * deproto(protonum)
  148.      int protonum;
  149. {
  150.  
  151. switch (protonum) {
  152.  
  153.  case 1: return("icmp");
  154.  case 2: return("igmp");
  155.  case 3: return("ggp");
  156.  case 5: return("st");
  157.  case 6: return("tcp");
  158.  case 7: return("ucl");
  159.  case 8: return("egp");
  160.  case 9: return("igp");
  161.  case 11: return("nvp-II");
  162.  case 12: return("pup");
  163.  case 16: return("chaos");
  164.  case 17: return("udp");
  165.  default: (void) sprintf(wksbuf, "%d", protonum);
  166.    return(wksbuf);
  167. }
  168. }
  169.  
  170. p_query(msg)
  171.     char *msg;
  172. {
  173. #ifdef DEBUG
  174.     fp_query(msg,stdout);
  175. #endif
  176. }
  177.  
  178. char *
  179. do_rrset(msg,cp,cnt,pflag,file,hs)
  180.      int cnt, pflag;
  181.      char *cp,*msg, *hs;
  182.      FILE *file;
  183. {
  184.   int n;
  185.   char *pp;
  186.   char *t1, *t2, *list[100],**tt;
  187.   int sflag;
  188.     /*
  189.      * Print  answer records
  190.      */
  191.   sflag = (pfcode & pflag);
  192.   if (n = ntohs(cnt)) {
  193.     *list=NULL;
  194.     if ((sflag) && (pfcode & PRF_HEAD1))
  195.       fprintf(file,hs);
  196.     while (--n >= 0) {
  197.       pp = (char *) malloc(512);
  198.       *pp=0;
  199.       cp = p_rr(cp, msg, pp);
  200.       if ((cp-msg) > PACKETSZ)
  201.     return (NULL);
  202.  
  203.       if (sflag) {
  204.     if (pfcode & PRF_SORT) {
  205.       for (tt=list, t1=pp, t2=NULL;
  206.            ((*tt != NULL) && (strcmp(*tt,t1) < 1));) {
  207.         tt++;
  208.       }
  209.       while (t1 != NULL) {
  210.         t2 = *tt;
  211.         *tt++ = t1;
  212.         t1 = t2;
  213.       }
  214.       *tt = t1;
  215.     }
  216.     else {
  217.       fprintf(file,"%s",pp);
  218.       free(pp);
  219.     }
  220.       } else
  221.     free(pp);
  222.     }
  223.  
  224.     if (pfcode & pflag) {
  225.       if (pfcode & PRF_SORT) {
  226.     tt=list;
  227.     while (*tt != NULL) {
  228.       fprintf(file,"%s",*tt);
  229.       free(*tt++);
  230.     }
  231.       }
  232.       if (pfcode & PRF_HEADX)
  233.     fprintf(file,"\n");
  234.     }
  235.   }
  236.   return(cp);
  237. }
  238.  
  239.  
  240. /*
  241.  * Print the contents of a query.
  242.  * This is intended to be primarily a debugging routine.
  243.  */
  244. fp_query(msg,file)
  245.     char *msg;
  246.     FILE *file;
  247. {
  248.     register char *cp;
  249.     register HEADER *hp;
  250.     register int n;
  251.     char zfile[256], tfile[100];
  252.  
  253.     /*
  254.      * Print header fields.
  255.      */
  256.     hp = (HEADER *)msg;
  257.     cp = msg + sizeof(HEADER);
  258.     if ((pfcode & PRF_HEADX) || hp->rcode) {
  259.       fprintf(file,";; ->>HEADER<<- ");
  260.       fprintf(file,"opcode: %s ", _res_opcodes[hp->opcode]);
  261.       fprintf(file,", status: %s", _res_resultcodes[hp->rcode]);
  262. /*      if (pfcode & PRF_TTLID)  XXXX */
  263.         fprintf(file,", id: %d", ntohs(hp->id));
  264.       putc('\n',file);
  265.     }
  266.     if (pfcode & PRF_HEAD2) {
  267.       fprintf(file,";; flags:");
  268.       if (hp->qr)
  269.         fprintf(file," qr");
  270.       if (hp->aa)
  271.         fprintf(file," aa");
  272.       if (hp->tc)
  273.         fprintf(file," tc");
  274.       if (hp->rd)
  275.         fprintf(file," rd");
  276.       if (hp->ra)
  277.         fprintf(file," ra");
  278.       if (hp->pr)
  279.         fprintf(file," pr");
  280.       if (_res.options & RES_DEBUG2)
  281.         fprintf(file," res_opts: %x", _res.options);
  282.       putc(' ',file);
  283.     }
  284.     if (pfcode & PRF_HEAD1) {
  285.       fprintf(file,"; Ques: %d, ", ntohs(hp->qdcount));
  286.       fprintf(file,"Ans: %d, ", ntohs(hp->ancount));
  287.       fprintf(file,"Auth: %d, ", ntohs(hp->nscount));
  288.       fprintf(file,"Addit: %d", ntohs(hp->arcount));
  289.     }
  290.     if (pfcode & (PRF_HEADX | PRF_HEAD2 | PRF_HEAD1))
  291.       putc('\n',file);
  292.     /*
  293.      * Print question records.
  294.      */
  295.     if (n = ntohs(hp->qdcount)) {
  296.       if (pfcode & PRF_QUES)
  297.         fprintf(file,";; QUESTIONS: \n");
  298.       while (--n >= 0) {
  299.         sprintf(zfile,";;\t");
  300.         cp = p_cdname(cp, msg, zfile);
  301.         if (cp == NULL)
  302.           return;
  303.         sprintf(tfile,", type = %s", p_type(_getshort(cp)));
  304.         strcat(zfile,tfile);
  305.         cp += sizeof(u_short);
  306.         sprintf(tfile,", class = %s\n", p_class(_getshort(cp)));
  307.         strcat(zfile,tfile);
  308.         cp += sizeof(u_short);
  309.         if (pfcode & PRF_QUES)
  310.           fprintf(file,"%s",zfile);
  311.       }
  312.       if (pfcode & PRF_QUES)
  313.           fprintf(file,"\n");
  314.     }
  315.  
  316.     /*
  317.      * Print authoritative answer records
  318.      */
  319.  
  320. if ((cp = do_rrset(msg,cp,hp->ancount,PRF_ANS,file,";; ANSWERS:\n")) == NULL)
  321.   return;
  322.  
  323.     /*
  324.      * print name server records
  325.      */
  326.  
  327. if ((cp = do_rrset(msg,cp,hp->nscount,PRF_AUTH,file,
  328.            ";; AUTHORITY RECORDS:\n")) == NULL)
  329.   return;
  330.  
  331.     /*
  332.      * print additional records
  333.      */
  334.  
  335. if ((cp = do_rrset(msg,cp,hp->arcount,PRF_ADD,file,
  336.            ";; ADDITIONAL RECORDS:\n")) == NULL)
  337.   return;
  338.  
  339. } /* end function */
  340.  
  341.       
  342.  
  343. char *
  344. p_cdname(cp, msg, p)
  345.     char *cp, *msg;
  346.         char *p;
  347. {
  348. #ifdef DEBUG
  349.     char name[MAXDNAME];
  350.     int n;
  351.  
  352.     if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0)
  353.         return (NULL);
  354.     if (name[0] == '\0') {
  355.         name[0] = '.';
  356.         name[1] = '\0';
  357.     }
  358.     strcat(p,name);
  359.     return (cp + n);
  360. #endif
  361. }
  362.  
  363.  
  364.  
  365. /********************************************************
  366.  * Print resource record fields in human readable form.
  367.  ********************************************************/
  368. char *
  369. p_rr(cp, msg,p)
  370.     char *cp, *msg, *p;
  371. {
  372. #ifdef DEBUG
  373.     int type, class, dlen, n, c, xx,lcnt;
  374.     struct in_addr inaddr;
  375.     char *cp1;
  376.     unsigned long tmpttl;
  377.         struct servent *service;
  378.     struct protoent *protocol;
  379.     char file[130];
  380.  
  381.     if ((cp = p_cdname(cp, msg, p)) == NULL)
  382.         return (NULL);            /* compression error */
  383.  
  384.     if (*(p+strlen(p)-1) != '.')
  385.       strcat(p,".");
  386.  
  387.     type = _getshort(cp);
  388.     cp += sizeof(u_short);
  389.     class = _getshort(cp);
  390.     cp += sizeof(u_short);
  391.     tmpttl = _getlong(cp);
  392.     cp += sizeof(u_long);
  393.  
  394.     if (pfcode & PRF_TTLID) {
  395.       sprintf(file,"\t%d",tmpttl);
  396.       strcat(p,file);
  397.     }
  398.  
  399.     if (pfcode & PRF_CLASS)
  400.       sprintf(file,"\t%s\t%s",p_class(class), p_type(type));
  401.     else
  402.       sprintf(file,"\t%s", p_type(type));
  403.     strcat(p, file);
  404.  
  405.     dlen = _getshort(cp);
  406.     cp += sizeof(u_short);
  407.     cp1 = cp;
  408.     /*
  409.      * Print type specific data, if appropriate
  410.      */
  411.     switch (type) {
  412.     case T_A:
  413.         switch (class) {
  414.         case C_IN:
  415.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  416.             if (dlen == 4) {
  417.                     sprintf(file,"\t%s",inet_ntoa(inaddr));
  418.                 strcat(p,file);
  419.                 cp += dlen;
  420.             } else if (dlen == 7) {
  421.                 strcat(p,inet_ntoa(inaddr));
  422.                 sprintf(file,";; proto: %d", cp[4]);
  423.                 strcat(p,file);
  424.                 sprintf(file,", port: %d",
  425.                     (cp[5] << 8) + cp[6]);
  426.                 strcat(p,file);
  427.                 cp += dlen;
  428.             }
  429.             break;
  430.         default:
  431.             cp += dlen;
  432.         }
  433.         break;
  434.     case T_CNAME:
  435.     case T_MB:
  436. #ifdef OLDRR
  437.     case T_MD:
  438.     case T_MF:
  439. #endif /* OLDRR */
  440.     case T_MG:
  441.     case T_MR:
  442.     case T_NS:
  443.     case T_PTR:
  444.         strcat(p,"\t");
  445.         cp = p_cdname(cp, msg, p);
  446.         strcat(p,".");
  447.         break;
  448.  
  449.     case T_HINFO:
  450.         if (n = *cp++) {
  451.             sprintf(file,"\t%.*s ", n, cp);
  452.             strcat(p,file);
  453.             cp += n;
  454.         }
  455.         if (n = *cp++) {
  456.             sprintf(file,"%.*s", n, cp);
  457.             strcat(p,file);
  458.             cp += n;
  459.         }
  460.         break;
  461.  
  462.     case T_UINFO:
  463.         sprintf(file,"\t%s", cp);
  464.         strcat(p,file);
  465.         cp += dlen;
  466.         break;
  467.  
  468.     case T_TXT:
  469.         xx=0;
  470.         while (xx++<dlen) {
  471.           if (n = *cp++) {
  472.             sprintf(file,"\t%.*s",n,cp);
  473.             strcat(p,file);
  474.             cp += (n-1);
  475.             xx += n;
  476.             if (*cp++ != '\n')
  477.               strcat(p,"\n");
  478.           }
  479.         }
  480.         strcat(p,"\n");
  481.         break;
  482.  
  483.     case T_SOA:
  484.         strcat(p,"\t");
  485.         cp = p_cdname(cp, msg, p);
  486.         strcat(p,".  ");
  487.         cp = p_cdname(cp, msg, p);
  488.         sprintf(file,". (\n\t\t\t%ld\t;serial\n", _getlong(cp));
  489.         strcat(p,file);
  490.         cp += sizeof(u_long);
  491.         sprintf(file,"\t\t\t%ld\t;refresh\n", _getlong(cp));
  492.         strcat(p,file);
  493.         cp += sizeof(u_long);
  494.         sprintf(file,"\t\t\t%ld\t;retry\n", _getlong(cp));
  495.         strcat(p,file);
  496.         cp += sizeof(u_long);
  497.         sprintf(file,"\t\t\t%ld\t;expire\n", _getlong(cp));
  498.         strcat(p,file);
  499.         cp += sizeof(u_long);
  500.         sprintf(file,"\t\t\t%ld )\t;minim\n", _getlong(cp));
  501.         strcat(p,file);
  502.         cp += sizeof(u_long);
  503.         break;
  504.  
  505.     case T_MX:
  506.         sprintf(file,"\t%ld ",_getshort(cp));
  507.         strcat(p,file);
  508.         cp += sizeof(u_short);
  509.         cp = p_cdname(cp, msg, p);
  510.         strcat(p,".");
  511.         break;
  512.  
  513.     case T_MINFO:
  514.         strcat(p,"\t");
  515.         cp = p_cdname(cp, msg, p);
  516.         strcat(p,". ");
  517.         cp = p_cdname(cp, msg, p);
  518.         strcat(p,". ");
  519.         break;
  520.  
  521.  
  522.     case T_UID:
  523.     case T_GID:
  524.         if (dlen == 4) {
  525.             sprintf(file,"\t%ld", _getlong(cp));
  526.             strcat(p,file);
  527.             cp += sizeof(int);
  528.         }
  529.         break;
  530.  
  531.     case T_WKS:
  532.         if (dlen < sizeof(u_long) + 1)
  533.             break;
  534.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  535.         cp += sizeof(u_long);
  536.  
  537. /* Although more portable, quite slow ...
  538.  
  539.         if ((protocol = getprotobynumber((int) *cp)) != NULL) {
  540.           sprintf(file,"\t %s %s (\n", inet_ntoa(inaddr),
  541.               protocol->p_name);
  542.         } else {
  543.           sprintf(file,"\t%s %d (\n", inet_ntoa(inaddr), *cp);
  544.         }
  545. */
  546.         sprintf(file, "\t %s %s (\n", inet_ntoa(inaddr),
  547.             deproto((int) *cp));
  548.  
  549.         cp++;
  550.         strcat(p,file);
  551.         n = 0;
  552.         strcat(p,"\t\t\t");
  553.                 lcnt = 5;
  554.         while (cp < cp1 + dlen) {
  555.             c = *cp++;
  556.             do {
  557.               if (c & 0200) {
  558.  
  559. /* Although more portable, quite slow ... even using set/endservent()
  560.  
  561.                  if ((service = getservbyport(n,NULL)) != NULL) {
  562.                    sprintf(file," %s", service->s_name);
  563.                  } else {
  564.                    sprintf(file, " %d", n);
  565.                  }
  566. */
  567.                 sprintf(file," %s", dewks(n));
  568.                 strcat(p,file);
  569.                  if (--lcnt == 0) {
  570.                    lcnt=5;
  571.                    strcat(p,"\n\t\t\t");
  572.                  }
  573.                }
  574.               c <<= 1;
  575.             } while (++n & 07);
  576.               }
  577.         strcat(p," )");
  578.         break;
  579.  
  580. #ifdef ALLOW_T_UNSPEC
  581.     case T_UNSPEC:
  582.         {
  583.             int NumBytes = 8;
  584.             char *DataPtr;
  585.             int i;
  586.  
  587.             if (dlen < NumBytes) NumBytes = dlen;
  588.             sprintf(file, "\tFirst %d bytes of hex data:",
  589.                 NumBytes);
  590.             strcat(p,file);
  591.         for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) {
  592.           sprintf(file, " %x", *DataPtr);
  593.           strcat(p,file);
  594.         }
  595.             strcat(p,"\n");
  596.             cp += dlen;
  597.         }
  598.         break;
  599. #endif /* ALLOW_T_UNSPEC */
  600.  
  601.     default:
  602.         strcat(p,"\t???\n");
  603.         cp += dlen;
  604.     }
  605. /*
  606.     if (pfcode & PRF_TTLID) {
  607.       sprintf(file,"\t; %d",tmpttl);
  608.       strcat(p,file);
  609.     }
  610. */
  611.     strcat(p,"\n");
  612.  
  613.     if (cp != cp1 + dlen)
  614.        fprintf(stdout,";; packet size error (%#x != %#x)\n", cp, cp1+dlen);
  615.     return (cp);
  616. #endif
  617. }
  618.  
  619. static    char nbuf[20];
  620.  
  621. /*
  622.  * Return a string for the type
  623.  */
  624. char *
  625. p_type(type)
  626.     int type;
  627. {
  628.     switch (type) {
  629.     case T_A:
  630.         return("A");
  631.     case T_NS:        /* authoritative server */
  632.         return("NS");
  633. #ifdef OLDRR
  634.     case T_MD:        /* mail destination */
  635.         return("MD");
  636.     case T_MF:        /* mail forwarder */
  637.         return("MF");
  638. #endif /* OLDRR */
  639.     case T_CNAME:        /* connonical name */
  640.         return("CNAME");
  641.     case T_SOA:        /* start of authority zone */
  642.         return("SOA");
  643.     case T_MB:        /* mailbox domain name */
  644.         return("MB");
  645.     case T_MG:        /* mail group member */
  646.         return("MG");
  647.     case T_MX:        /* mail routing info */
  648.         return("MX");
  649.     case T_MR:        /* mail rename name */
  650.         return("MR");
  651.     case T_NULL:        /* null resource record */
  652.         return("NULL");
  653.     case T_WKS:        /* well known service */
  654.         return("WKS");
  655.     case T_PTR:        /* domain name pointer */
  656.         return("PTR");
  657.     case T_HINFO:        /* host information */
  658.         return("HINFO");
  659.     case T_MINFO:        /* mailbox information */
  660.         return("MINFO");
  661.     case T_AXFR:        /* zone transfer */
  662.         return("AXFR");
  663.     case T_MAILB:        /* mail box */
  664.         return("MAILB");
  665.     case T_MAILA:        /* mail address */
  666.         return("MAILA");
  667.     case T_ANY:        /* matches any type */
  668.         return("ANY");
  669.         case T_TXT:
  670.         return("TXT");
  671.     case T_UINFO:
  672.         return("UINFO");
  673.     case T_UID:
  674.         return("UID");
  675.     case T_GID:
  676.         return("GID");
  677. #ifdef ALLOW_T_UNSPEC
  678.     case T_UNSPEC:
  679.         return("UNSPEC");
  680. #endif /* ALLOW_T_UNSPEC */
  681.     default:
  682.         (void)sprintf(nbuf, "%d", type);
  683.         return(nbuf);
  684.     }
  685. }
  686.  
  687. /*
  688.  * Return a mnemonic for class
  689.  */
  690. char *
  691. p_class(class)
  692.     int class;
  693. {
  694.  
  695.     switch (class) {
  696.     case C_IN:        /* internet class */
  697.         return("IN");
  698.     case C_ANY:        /* matches any class */
  699.         return("ANY");
  700.     default:
  701.         (void)sprintf(nbuf, "%d", class);
  702.         return(nbuf);
  703.     }
  704. }
  705.